package edu.asu.sapa.ground.update;

import java.util.Arrays;

import edu.asu.sapa.ground.Operator;
import edu.asu.sapa.ground.State;
import edu.asu.sapa.heuristic.PG;

public abstract class Load extends Update {
	public Update[] contents;

	public Load() {
	}
	
	public Load(Update[] array) {
		contents = array;
	}

	public abstract boolean load(State s, Context c);
	
	public boolean applicableBefore(State s, Context c) {
		boolean possible = true;
		for (Update u : contents) {
			possible &= u.applicableBefore(s,c);
		}
		return possible;
	}
	public boolean applicableAfter(State s, Context c) {
		boolean possible = true;
		for (Update u : contents) {
			possible &= u.applicableAfter(s,c);
		}
		return possible;
	}


	@Override
	public boolean finishAfter(State s, Context c, float time) {
		boolean possible = true;
		for (Update u : contents) {
			possible &= u.finishAfter(s,c,time);
		}
		return possible;
	}

	@Override
	public boolean finishBefore(State s, Context c, float time) {
		boolean possible = true;
		for (Update u : contents) {
			possible &= u.finishBefore(s,c,time);
		}
		return possible;
	}

	@Override
	public void relaxedFinish(PG pg, State s, Context c, float time) {
		for (Update u : contents) {
			u.relaxedFinish(pg,s,c,time);
		}
	}

	@Override
	public void relaxedStart(PG pg, State s, Context c, float time) {
		for (Update u : contents) {
			u.relaxedStart(pg,s,c,time);
		}
	}

	@Override
	public void relaxedUpdate(PG pg, State s, Context c, float time) {
		for (Update u : contents) {
			u.relaxedUpdate(pg,s,c,time);
		}
	}

	@Override
	public boolean startAfter(State s, Context c, float time) {
		boolean possible = true;
		for (Update u : contents) {
			possible &= u.startAfter(s,c,time);
		}
		return possible;
	}

	@Override
	public boolean startBefore(State s, Context c, float time) {
		boolean possible = true;
		for (Update u : contents) {
			possible &= u.startBefore(s,c,time);
		}
		return possible;
	}

	@Override
	public boolean updateAfter(State s, Context c, float time) {
		boolean possible = true;
		for (Update u : contents) {
			possible &= u.updateAfter(s,c,time);
		}
		return possible;
	}

	@Override
	public boolean updateBefore(State s, Context c, float time) {
		boolean possible = true;
		for (Update u : contents) {
			possible &= u.updateBefore(s,c,time);
		}
		return possible;
	}

	public boolean analyzeStatic(float dur) {
		int size = contents.length;
		int i=0;
		while (i<size) {
			Update u = contents[i];
			if (!u.analyzeStatic(dur)) {
				contents = null;
				return false;
			}
			if (u.isNoOp()) {
				contents[i] = contents[--size];
			} else {
				++i;
			}
		}
		if (size != contents.length)
			contents = Arrays.copyOf(contents,size);
		return true;
	}

	public void removeDependencies(Operator o) {
		for (Update u : contents) {
			u.removeDependencies(o);
		}
	}
	public void setDependencies(Operator o) {
		for (Update u : contents) {
			u.setDependencies(o);
		}
	}
	
	public boolean isFail() {
		return contents == null;
	}
	
	public boolean isNoOp() {
		return contents != null && contents.length == 0;
	}
	
	public String toString() {
		String s="";
		s += "(and\n";
		for (Update u : contents)
			s += "\t\t" + u + "\n";
		s += "\t))\n";
		return s;
	}
	
	public int compareTo(Update o) {
		return 0;
	}


}
